package org.systemsbiology.bigquery.gae.servlets;

import com.google.api.services.bigquery.model.Bigqueryfield;
import com.google.api.services.bigquery.model.DatasetListDatasets;
import com.google.api.services.bigquery.model.Table;
import com.google.api.services.bigquery.model.TableListTables;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.systemsbiology.bigquery.gae.utils.BQUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static org.apache.commons.lang.StringUtils.*;

/**
 * @author hrovira
 */
public class DatasetsRestServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            String uri = request.getRequestURI();
            if (equalsIgnoreCase(uri, "/datasets")) {
                outputDatasets(response);
                return;
            }

            String datasetId = chomp(substringAfter(uri, "/datasets/"), "/");
            String tableId = null;
            if (contains(datasetId, "/")) {
                tableId = chomp(substringAfterLast(uri, "/"), "/");
                datasetId = chomp(substringBetween(uri, "/datasets/", tableId), "/");
            }

            if (!isEmpty(datasetId) && !isEmpty(tableId)) {
                outputTable(datasetId, tableId, response);
                return;
            }

            if (!isEmpty(datasetId)) {
                outputDataset(datasetId, response);
                return;
            }

            response.setStatus(SC_NOT_FOUND);
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }

    /*
     * Private Methods
     */
    private void outputDatasets(HttpServletResponse response) throws Exception {
        BQUtils bqUtils = new BQUtils();

        JsonArray datasets = new JsonArray();

        for (DatasetListDatasets dld : bqUtils.getDatasets()) {
            JsonObject json = new JsonObject();
            String dldId = dld.getId();
            if (contains(dldId, ":")) {
                dldId = substringAfterLast(dldId, ":");
            }
            json.addProperty("uri", "/datasets/" + dldId);
            json.addProperty("name", dldId);
            json.addProperty("label", dld.getFriendlyName());
            datasets.add(json);
        }

        JsonObject json = new JsonObject();
        json.addProperty("uri", "/datasets");
        json.addProperty("numberOfItems", datasets.size());
        json.add("items", datasets);

        response.setContentType("application/json");
        response.getWriter().write(json.toString());
    }

    private void outputDataset(String datasetId, HttpServletResponse response) throws Exception {
        JsonArray tables = new JsonArray();
        BQUtils bqUtils = new BQUtils();

        for (TableListTables tlt : bqUtils.getTables(datasetId)) {
            JsonObject json = new JsonObject();
            String tltid = tlt.getId();
            if (contains(tltid, datasetId)) {
                tltid = substringAfterLast(tltid, datasetId + ".");
            }
            json.addProperty("uri", "/datasets/" + datasetId + "/" + tltid);
            json.addProperty("name", tltid);
            json.addProperty("tableId", substringAfter(tlt.getId(), ":"));
            json.addProperty("label", tlt.getFriendlyName());
            tables.add(json);
        }

        JsonObject json = new JsonObject();
        json.addProperty("uri", "/datasets/" + datasetId);
        json.addProperty("numberOfItems", tables.size());
        json.add("items", tables);

        response.setContentType("application/json");
        response.getWriter().write(json.toString());
    }

    private void outputTable(String datasetId, String tableId, HttpServletResponse response) throws Exception {
        BQUtils bqUtils = new BQUtils();

        Table t = bqUtils.getTable(datasetId, tableId);

        JsonArray columns = new JsonArray();
        for (Bigqueryfield field : t.getSchema().getFields()) {
            JsonObject column = new JsonObject();
            column.addProperty("name", field.getName());
            column.addProperty("type", field.getType());
            column.addProperty("mode", field.getMode());
            columns.add(column);
        }

        JsonObject json = new JsonObject();
        json.addProperty("uri", "/datasets/" + datasetId + "/" + tableId);
        json.addProperty("numberOfItems", columns.size());
        json.add("items", columns);

        response.setContentType("application/json");
        response.getWriter().write(json.toString());
    }

}
